home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 2
/
Nebula Two.iso
/
SourceCode
/
daymisckit_proj
/
daymisckit-1
/
DAYTime.m
< prev
next >
Wrap
Text File
|
1995-06-12
|
11KB
|
444 lines
//
// DAYTime.m -- a generic class to simplify manipulation of times
// Written by Don Yacktman (c) 1993 by Don Yacktman.
// Version 1.0. All rights reserved.
//
// This is a free object! Contact the author for the latest version.
// Don Yacktman, 4279 N. Ivy Lane, Provo, UT, 84604
// e-mail: Don_Yacktman@byu.edu
//
// You may use and copy this class freely as long as you
// comply with the following terms:
// (1) Do not remove the author's name or any of the
// copyright notices from this file.
// (2) If you redistribute an application which uses this
// object, you must either include the source code for
// this object with the application or state in your
// application's documentation that you (a) use this
// object and (b) where to obtain the source code for
// the object.
// (3) In no way shall the author or his employer(s) be held
// responsible for any damages caused by what this object
// does or does not do.
// (4) You have no warranty whatsoever that this object is
// good for any purpose at all. If you find it useful
// for something, consider yourself lucky and leave it at that.
//
// ***** denotes an unfinished/unimplemented method.
#import <daymisckit/DAYTime.h>
#import <sys/time.h>
// a few functions to handle date wierdnesses
int isLeapYear(int year)
{
// *****
return 0;
}
int DAY_daysUpTo(int month, int year)
{
int array[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
if (month < 2) return array[month];
return (array[month] + isLeapYear(year));
}
int DAY_daysIn(int month, int year)
{
int array[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (month != 1) return array[month];
return (array[month] + isLeapYear(year));
}
@implementation DAYTime
- init
{
id ret;
if (!_initted) ret = [super init];
else ret = self;
_initted = YES;
dow = DAY_UNKNOWN_DOW;
if (!myStringValue) myStringValue = (char *)malloc(256);
year = 0; day = 0; month = 0; hour = 0;
minute = 0; second = 0; microsecond = 0;
isRelative = NO;
return ret;
}
- initWithCurrentTime
{
struct timeval tp;
struct timezone tzp;
struct tm *tv;
id ret = [self init];
gettimeofday(&tp, &tzp);
tv = localtime(&tp.tv_sec);
microsecond = tp.tv_usec;
second = tv->tm_sec;
minute = tv->tm_min;
hour = tv->tm_hour;
day = tv->tm_mday - 1;
dow = tv->tm_wday;
month = tv->tm_mon;
year = tv->tm_year;
return ret;
}
- calcDayOfWeek
{
// *****
return self;
}
- setYear:(int)t { year = t; dow = DAY_UNKNOWN_DOW; return self; }
- setMonth:(int)t { month = t; dow = DAY_UNKNOWN_DOW; return self; }
- setDayOfWeek:(int)t { dow = t; return self; }
- setDay:(int)t { day = t; dow = DAY_UNKNOWN_DOW; return self; }
- setHour:(int)t { hour = t; return self; }
- setMinute:(int)t { minute = t; return self; }
- setSecond:(int)t { second = t; return self; }
- setMicrosecond:(int)t { microsecond = t; return self; }
- setRelative:(BOOL)t { isRelative = t; return self; }
- (int)_nintValue // ignores usecs.
{ // ***** Not quite right; ignores leap years
return ((((((year - 1970) * DAY_MAX_DAYS
+ DAY_daysUpTo(month, year) + day)
* DAY_MAX_HOURS) + hour)
* DAY_MAX_MINUTES + minute)
* DAY_MAX_SECONDS + second);
}
- (int)intValue // # seconds since Jan 1, 1970
{ // rounds usec. and add in...
return ([self _nintValue] +
((microsecond < DAY_MAX_MICROSECONDS / 2) ? 0 : 1));
}
- (double)doubleValue
{
// *****
return 0.0;
}
- (float)floatValue
{
// *****
return 0.0;
}
- (const char *)stringValue
{ // Need to allow the user to set the time and/or date format! *****
// Don't free this! that's why it's a const!
if (!myStringValue) myStringValue = (char *)malloc(256);
sprintf(myStringValue, "%ld : %ld : %ld", hour, minute, second);
return myStringValue;
}
- free
{
free(myStringValue);
return [super free];
}
- (int)dayOfWeek
{
if (dow < 0) [self calcDayOfWeek];
return dow;
}
- (int)year { return year; }
- (int)month { return month; }
- (int)day { return day; }
- (int)hour { return hour; }
- (int)minute { return minute; }
- (int)second { return second; }
- (int)microsecond { return microsecond; }
- (BOOL)isRelative { return isRelative; }
- addTime:aTime
{
if (![aTime isKindOf:[DAYTime class]]) return nil;
[self addMicroseconds:[aTime microsecond]];
[self addSeconds:[aTime second]];
[self addMinutes:[aTime minute]];
[self addHours:[aTime hour]];
[self addDays:[aTime day]];
[self addMonths:[aTime month]];
[self addYears:[aTime year]];
return self;
}
- subtractTime:aTime
{
if (![aTime isKindOf:[DAYTime class]]) return nil;
[self subtractMicroseconds:[aTime microsecond]];
[self subtractSeconds:[aTime second]];
[self subtractMinutes:[aTime minute]];
[self subtractHours:[aTime hour]];
[self subtractDays:[aTime day]];
[self subtractMonths:[aTime month]];
[self subtractYears:[aTime year]];
return self;
}
- addMicroseconds:(long)t
{
long x = [self microsecond] + t;
if (!t) return self;
[self setMicrosecond:(x % DAY_MAX_MICROSECONDS)];
[self addSeconds:(x / DAY_MAX_MICROSECONDS)];
return self;
}
- addSeconds:(long)t
{
long x = [self second] + t;
if (!t) return self;
[self setSecond:(x % DAY_MAX_SECONDS)];
[self addMinutes:(x / DAY_MAX_SECONDS)];
return self;
}
- addMinutes:(long)t
{
long x = [self minute] + t;
if (!t) return self;
[self setMinute:(x % DAY_MAX_MINUTES)];
[self addHours:(x / DAY_MAX_MINUTES)];
return self;
}
- addHours:(long)t
{
long x = [self hour] + t;
if (!t) return self;
[self setHour:(x % DAY_MAX_HOURS)];
[self addDays:(x / DAY_MAX_HOURS)];
return self;
}
- addDays:(long)t
{
long x = [self day] + t; int k;
if (!t) return self;
k = DAY_daysIn(month, year);
while (x >= k) { // This is slow, but it works.
[self addMonths:1];
x -= k; k = DAY_daysIn(month, year);
}
[self setDay:(x % DAY_MAX_DAYS)];
return self;
}
- addWeeks:(long)t
{
return [self addDays:(t * 7)];
}
- addMonths:(long)t
{
long x = [self month] + t;
if (!t) return self;
[self setMonth:(x % DAY_MAX_MONTHS)];
[self addYears:(x / DAY_MAX_MONTHS)];
return self;
}
- addYears:(long)t
{
if (t) [self setYear:([self year] + t)];
return self;
}
- (BOOL)isAfter:aTime
{ // returns YES if we are "older" than time passed in
int si = [self _nintValue];
int oi = [aTime _nintValue];
if (si > oi) return YES;
if ((si == oi) && ([self microsecond] > [aTime microsecond])) return YES;
return NO;
}
- (BOOL)isEqual:aTime
{ // returns YES if we are "same" as time passed in
if (([self _nintValue] == [aTime _nintValue]) &&
([self microsecond] == [aTime microsecond])) return YES;
return NO;
}
- subtractMicroseconds:(long)t
{
long us = t % DAY_MAX_MICROSECONDS;
long s = t / DAY_MAX_MICROSECONDS;
long sus = [self microsecond];
if (us > sus) { s++; sus += DAY_MAX_MICROSECONDS; }
[self subtractSeconds:s];
[self setMicrosecond:(sus - us)];
return self;
}
- subtractSeconds:(long)t
{
long s = t % DAY_MAX_SECONDS;
long m = t / DAY_MAX_SECONDS;
long ss = [self second];
if (s > ss) { m++; ss += DAY_MAX_SECONDS; }
[self subtractMinutes:m];
[self setSecond:(ss - s)];
return self;
}
- subtractMinutes:(long)t
{
long m = t % DAY_MAX_MINUTES;
long h = t / DAY_MAX_MINUTES;
long sm = [self minute];
if (m > sm) { h++; sm += DAY_MAX_MINUTES; }
[self subtractHours:h];
[self setMinute:(sm - m)];
return self;
}
- subtractHours:(long)t
{
long h = t % DAY_MAX_HOURS;
long d = t / DAY_MAX_HOURS;
long sh = [self hour];
if (h > sh) { d++; sh += DAY_MAX_HOURS; }
[self subtractDays:d];
[self setHour:(sh - h)];
return self;
}
- subtractDays:(long)t
{
long sd = [self day];
while (t > sd) { // this is slow, but it works.
sd += DAY_daysIn(month, year);
[self subtractMonths:1];
}
[self setDay:(sd - t)];
return self;
}
- subtractWeeks:(long)t
{
return [self subtractDays:(t * 7)];
}
- subtractMonths:(long)t
{
long m = t % DAY_MAX_MONTHS;
long y = t / DAY_MAX_MONTHS;
long sm = [self month];
if (m > sm) { y++; sm += DAY_MAX_MONTHS; }
[self subtractYears:y];
[self setMonth:(sm - m)];
return self;
}
- subtractYears:(long)t
{
if (t) [self setYear:([self year] - t)];
return self;
}
- copy
{
id myCopy = [[DAYTime alloc] init];
[myCopy setYear:year];
[myCopy setMonth:month];
[myCopy setDay:day];
[myCopy setDayOfWeek:dow];
[myCopy setHour:hour];
[myCopy setMinute:minute];
[myCopy setSecond:second];
[myCopy setMicrosecond:microsecond];
[myCopy setRelative:isRelative];
return myCopy;
}
- copyTimeFrom:aTime
{
[self setYear:[aTime year]];
[self setMonth:[aTime month]];
[self setDay:[aTime day]];
[self setDayOfWeek:[aTime dayOfWeek]];
[self setHour:[aTime hour]];
[self setMinute:[aTime minute]];
[self setSecond:[aTime second]];
[self setMicrosecond:[aTime microsecond]];
[self setRelative:[aTime isRelative]];
return self;
}
- read:(NXTypedStream *)stream
{
[super read:stream];
NXReadTypes(stream, "cllllllll", &isRelative, µsecond, &second,
&minute, &hour, &dow, &day, &month, &year);
if (!myStringValue) myStringValue = (char *)malloc(256);
return self;
}
- write:(NXTypedStream *)stream
{
[super write:stream];
NXWriteTypes(stream, "cllllllll", &isRelative, µsecond, &second,
&minute, &hour, &dow, &day, &month, &year);
return self;
}
// NXTransport protocol implementation:
- encodeUsing:(id <NXEncoding>)portal
{
[portal encodeData:&isRelative ofType:"c"];
[portal encodeData:µsecond ofType:"i"];
[portal encodeData:&second ofType:"i"];
[portal encodeData:&minute ofType:"i"];
[portal encodeData:&hour ofType:"i"];
[portal encodeData:&dow ofType:"i"];
[portal encodeData:&day ofType:"i"];
[portal encodeData:&month ofType:"i"];
[portal encodeData:&year ofType:"i"];
return self;
}
- decodeUsing:(id <NXDecoding>)portal
{
[portal decodeData:&isRelative ofType:"c"];
[portal decodeData:µsecond ofType:"i"];
[portal decodeData:&second ofType:"i"];
[portal decodeData:&minute ofType:"i"];
[portal decodeData:&hour ofType:"i"];
[portal decodeData:&dow ofType:"i"];
[portal decodeData:&day ofType:"i"];
[portal decodeData:&month ofType:"i"];
[portal decodeData:&year ofType:"i"];
return self;
}
- encodeRemotelyFor:(NXConnection *)connection
freeAfterEncoding:(BOOL *)flagp isBycopy:(BOOL)isByCopy
{
if (isByCopy) {
*flagp = NO; // object will copy.
return self; //encode object (copy it)
}
*flagp = NO; // object will copy.
// super will encode the proxy otherwise
return [super encodeRemotelyFor:connection
freeAfterEncoding:flagp isBycopy:isByCopy];
}
@end